#pragma once

#include <sys/stat.h> //mkdir
#include <unistd.h> //access
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <fstream>

typedef struct info {
    unsigned char mode;
    char type[10];
    char name[100];
    char comment[200];
} Typeinfo;

class Filepair {
public:
    Filepair(const char *p)
            : path(p) {
    }

    ~Filepair() {}

private:
    std::string path;

};

class ITemplate {
public:
    ITemplate(char *t)
            : dirname(t), timeInfo() {
        time_t lt;
        lt = time(NULL);
        timeInfo += ctime(&lt);
        std::string readme = "# ";
        readme += t;
        readme += "\n\nThis file is generated by genProj program.";
        readme += "\n\t\tGenerated at ";
        readme += timeInfo;
        append("README.md", readme);
    }

    ITemplate(char *t, char *comment)
            : dirname(t), timeInfo() {
        time_t lt;
        lt = time(NULL);
        timeInfo += ctime(&lt);
        std::string readme = "# ";
        readme += t;
        readme += "\n";
        readme += comment;
        readme += "\n\nThis file is generated by genProj program.";
        readme += "\n\t\tGenerated at ";
        readme += timeInfo;
        append("README.md", readme);
    }

    virtual ~ITemplate() {}

    void createDir() {
        if (access(dirname, 0) == 0) {
            printf("directory: %s exist!\n", dirname);
            exit(-2);
        } else {
            if (mkdir(dirname, 0755)) {
                printf("create file failed!\n");
                exit(-2);
            }
        }
    }

    void append(const std::string name, const std::string content) {
        filename.push_back(name);
        filecontent.push_back(content);
    }

    int size() {
        return filename.size();
    }

    void flush() {
        int filesize = filename.size();
        for (int i = 0; i < filesize; i++) {
            std::string currentfile = dirname;
            currentfile += "/";
            currentfile += filename[i];

            std::ofstream fileout;
            fileout.open(currentfile, std::ios::out | std::ios::trunc);
            if (fileout.is_open()) {
                fileout << filecontent[i];
                fileout.close();
            }
        }
    }

    void operator()() {
        Process();
    }

protected:
    const char *dirname;
    std::string timeInfo;
private:

    std::vector <std::string> filename;
    std::vector <std::string> filecontent;

    virtual void Process() = 0;
};
